/**
 * jsonrpc访问edge
 * @author zhanglei
 */
// import axios from 'axios'
// // 请求路径以实际项目为准
// const JSONRPC_URL = 'http://192.168.3.74:8084'

import { post as Post } from '../../http'

const JSONRPC_PATH = '/jsonrpc'
const JSONRPC_VERSION = '2.0'
const USER_ID = 'admin'
const USER_NAME = 'admin'
const USER_ROLE = 'ADMIN'
const METHOD_EXEC_CMD = 'execCmd'
const METHOD_EXEC_CMD_AND_OUT = 'execCmdAndOut'
const METHOD_SET_COMPONENT_JSON = 'setComponentJson'
const METHOD_GET_COMPONENT_JSON = 'getComponentJson'
const METHOD_GET_COMPONENT_KEY = 'getComponentKey'
const METHOD_GET_ALL_JSON_KEY = 'getAllJsonKey'
const METHOD_CREATE_COMPONENT_CONFIG = 'createComponentConfig'
const METHOD_GET_COMPONENTS_CONFIG = 'getComponentsConfig'
const METHOD_GET_COMPONENTS_AND_COMM_CONFIG = 'getComponentsAndCommConfig'
const METHOD_GET_COMPONENT_CONFIG = 'getComponentConfig'
const METHOD_GET_COMPONENT_CHANNELS = 'getComponentChannels'
const METHOD_UPDATE_COMPONENT_CONFIG = 'updateComponentConfig'
const METHOD_UPDATE_COMPONENT_ASSIGN_CONFIG = 'updateComponentAssignConfig'
const METHOD_ENABLED_COMPONENT_CONFIG = 'enableComponentConfig'
const METHOD_DISABLED_COMPONENT_CONFIG = 'disableComponentConfig'
const METHOD_SET_CHANNEL_VALUE = 'setChannelValue'
const METHOD_BATCH_SET_CHANNEL_VALUE = 'batchSetChannelValue'
const METHOD_SET_UI_VIEW_JSON = 'setUiViewJson'
const METHOD_GET_UI_VIEW_JSON = 'getUiViewJson'
const SEARCH_COMPONENTS = 'searchComponents'

// const instance = axios.create({
//   baseURL: JSONRPC_URL,
//   timeout: 3000,
//   headers: {
//     'Content-Type': 'application/json'
//   }
// })

// instance.interceptors.request.use(
//   config => {
//     // 在发送请求之前做些什么
//     // 添加请求头等操作
//     return config
//   },
//   error => {
//     // 对请求错误做些什么
//     return Promise.reject(error)
//   }
// )
// instance.interceptors.response.use(
//   response => {
//     // 对响应数据做些什么
//     // 统一处理响应数据等操作
//     return response.data
//   },
//   error => {
//     // 对响应错误做些什么
//     // 统一处理错误等操作
//     return Promise.reject(error)
//   }
// )
const post = function (data) {
  let req = {
    ...createJsonrpcRequest(),
    ...data
  }
  return new Promise((resolve, reject) => {
    Post(JSONRPC_PATH, req)
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        console.log('post error', err)
        reject(err)
      })
  })
}
const success = function (data) {
  return {
    code: 200,
    msg: 'success',
    data: data
  }
}
const error = function (msg) {
  return {
    code: 400,
    msg: msg | 'error'
  }
}
const randomUUID = function () {
  let uuid = undefined
  try {
    uuid = window.crypto.randomUUID()
  } catch (e) {
    // console.error("browser random uuid error", e);
    uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = (Math.random() * 16) | 0,
        v = c === 'x' ? r : (r & 0x3) | 0x8
      return v.toString(16)
    })
  }
  return uuid
}
const createJsonrpcRequest = function () {
  let req = {
    id: randomUUID(),
    jsonrpc: JSONRPC_VERSION,
    params: {
      user: {
        id: USER_ID,
        name: USER_NAME,
        role: USER_ROLE
      }
    }
  }
  return req
}
/**
 * 执行linux命令，返回执行结果true/false
 * @param {linux命令} cmd
 */
const exec = function (cmd) {
  let req = {
    method: METHOD_EXEC_CMD,
    params: {
      cmd: cmd
    }
  }
  return post(req).then(resp => {
    if (resp.result && resp.result.code == 0) {
      return success(true)
    }
    console.error('result=', resp.result)
    return error(false)
  })
}
/**
 * 执行linux命令，返回输出内容
 * @param {linux命令} cmd
 * @returns object {out输出内容}
 */
const execAndOut = function (cmd) {
  let req = {
    method: METHOD_EXEC_CMD_AND_OUT,
    params: {
      cmd: cmd
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.out)
  })
}
/**
 * 设备保存json
 * @param {*} componentId
 * @param {*} key
 * @param {*} json
 * @returns object
 */
const setComponentJson = function (componentId, key, json) {
  let req = {
    method: METHOD_SET_COMPONENT_JSON,
    params: {
      componentId: componentId,
      key: key,
      json: json
    }
  }
  return post(req).then(resp => {
    if (resp.result && resp.result.code == 0) {
      return success(true)
    }
    console.error('result=', resp.result)
    return error(false)
  })
}
/**
 * 获取设备保存的json
 * @param {*} componentId
 * @param {*} key
 * @returns object
 */
const getComponentJson = function (componentId, key) {
  let req = {
    method: METHOD_GET_COMPONENT_JSON,
    params: {
      componentId: componentId,
      key: key
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.json)
  })
}
/**
 * 获取设备保存的json文件的key
 * @param {*} componentId
 * @param {*} key
 * @returns array:[key1, key2]
 */
const getComponentKey = function (componentId) {
  let req = {
    method: METHOD_GET_COMPONENT_KEY,
    params: {
      componentId: componentId
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.json)
  })
}
/**
 * 获取保存的全部json文件的key
 * @returns array:[key1, key2]
 */
const getAllJsonKey = function () {
  let req = {
    method: METHOD_GET_ALL_JSON_KEY,
    params: {}
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.json)
  })
}
/**
 * 创建设备
 *
 * @param {*} factoryPid edge设备类型ID
 * @param {*} properties [{"name":"id", "value":componentId}]
 * @returns
 */
const createComponent = function (factoryPid, properties) {
  let req = {
    method: METHOD_CREATE_COMPONENT_CONFIG,
    params: {
      factoryPid: factoryPid,
      properties: properties
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}
/**
 * 获取全部iot设备ID列表
 * @returns object{data}
 */
const getComponents = function () {
  let req = {
    method: METHOD_GET_COMPONENTS_CONFIG
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.components)
  })
}
/**
 * 获取全部iot设备ID和CommConfig列表
 * @returns object{data}
 */
const getComponentsAndCommConfig = function () {
  let req = {
    method: METHOD_GET_COMPONENTS_AND_COMM_CONFIG
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.components)
  })
}
/**
 * 获取iot设备ID配置
 * @returns object{data}
 */
const getComponent = function (componentId) {
  let req = {
    method: METHOD_GET_COMPONENT_CONFIG,
    params: {
      componentId: componentId
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}
/**
 * 获取iot设备全部channel数据
 * @returns object{data}
 */
const getComponentChannels = function (componentId) {
  let req = {
    method: METHOD_GET_COMPONENT_CHANNELS,
    params: {
      componentId: componentId
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}

/**
 * 更新iot设备配置
 * @param {*} componentId
 * @param {*} params [{"name":"属性名","value":""}]
 * @returns
 */
const updateComponent = function (componentId, params) {
  let req = {
    method: METHOD_UPDATE_COMPONENT_CONFIG,
    params: {
      componentId: componentId,
      properties: params
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}

/**
 * 更新iot设备指定部分配置
 * @param {*} componentId
 * @param {*} params [{"name":"属性名","value":""}]
 * @returns
 */
const updateComponentAssign = function (componentId, params) {
  let req = {
    method: METHOD_UPDATE_COMPONENT_ASSIGN_CONFIG,
    params: {
      componentId: componentId,
      properties: params
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}

/**
 * 设置设备channel值
 * @param {*} componentId
 * @param {*} channelId Channel(大驼峰命名)
 * @param {*} value
 * @returns
 */
const setChannelValue = function (componentId, channelId, value) {
  let req = {
    method: METHOD_SET_CHANNEL_VALUE,
    params: {
      componentId: componentId,
      channelId: channelId,
      value: value
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}

/**
 * 设置多个channel值
 * @param {*} componentId
 * @param {*} channelValues [{"channelId":"大驼峰命名","value":""}]
 * @returns
 */
const batchSetChannelValue = function (componentId, channelValues) {
  let req = {
    method: METHOD_BATCH_SET_CHANNEL_VALUE,
    params: {
      componentId: componentId,
      properties: channelValues
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}
/**
 * 启用设备
 * @param {*} componentId
 * @returns
 */
const enableComponent = function (componentId) {
  let req = {
    method: METHOD_ENABLED_COMPONENT_CONFIG,
    params: {
      componentId: componentId,
      properties: [
        {
          name: 'enabled',
          value: true
        }
      ]
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}
/**
 * 禁用设备
 * @param {*} componentId
 * @returns
 */
const disableComponent = function (componentId) {
  let req = {
    method: METHOD_DISABLED_COMPONENT_CONFIG,
    params: {
      componentId: componentId,
      properties: [
        {
          name: 'enabled',
          value: false
        }
      ]
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result)
  })
}
/**
 * UI界面保存json
 * @param {*} key
 * @param {*} json
 * @returns object
 */
const setUiViewJson = function (key, json) {
  let req = {
    method: METHOD_SET_UI_VIEW_JSON,
    params: {
      key: key,
      json: json
    }
  }
  return post(req).then(resp => {
    if (resp.result && resp.result.code == 0) {
      return success(true)
    }
    console.error('result=', resp.result)
    return error(false)
  })
}
/**
 * 获取UI界面保存的json
 * @param {*} key
 * @returns object
 */
const getUiViewJson = function (key) {
  let req = {
    method: METHOD_GET_UI_VIEW_JSON,
    params: {
      key: key
    }
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }
    return success(resp.result.json)
  })
}
/**
 * 使用jsonpath查询component
 * @param {jsonpath, filter, format} key
 * @returns object
 */
const searchComponents = function (params) {
  let req = {
    method: SEARCH_COMPONENTS,
    params: params
  }
  return post(req).then(resp => {
    if (!resp.result) {
      console.error('result=', resp.result)
      return error()
    }

    return success(resp.result.components)
  })
}

export {
  exec,
  execAndOut,
  setComponentJson,
  getComponentJson,
  getComponentKey,
  getAllJsonKey,
  createComponent,
  getComponents,
  getComponentsAndCommConfig,
  getComponent,
  getComponentChannels,
  updateComponent,
  updateComponentAssign,
  setChannelValue,
  batchSetChannelValue,
  enableComponent,
  disableComponent,
  setUiViewJson,
  getUiViewJson,
  searchComponents
}
